package cn.ywang.server;

import cn.ywang.annotation.RpcAnnotation;
import cn.ywang.register.IRegisterCenter;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 发布一个远程服务
 *
 * @Auther: BeatificWang
 * @Date: 2018/11/25 23:21
 */
public class Server {

	// 线程池
	private static final ExecutorService executorService = Executors.newCachedThreadPool();

	// 服务名称与地址的映射关系
	Map<String, Object> map = new HashMap<>();

	// 注册中心
	private IRegisterCenter registerCenter;

	// 服务地址
	private String serviceAddress;

	public Server(IRegisterCenter registerCenter, String serviceAddress) {
		this.registerCenter = registerCenter;
		this.serviceAddress = serviceAddress;
	}

	// 存储服务
	public void bind(Object... services) {
		for (Object service : services) {
			RpcAnnotation annotation = service.getClass().getAnnotation(RpcAnnotation.class);
			String serviceName = annotation.value().getName();
			String version = annotation.version();
			this.map.put(serviceName + "-" + version, service);
		}
	}

	/**
	 * 发布服务
	 */
	public void publisher() {
		ServerSocket serverSocket = null;
		try {
			String[] address = this.serviceAddress.split(":");
			int port = Integer.parseInt(address[1]);
			// 启动一个服务监听
			serverSocket = new ServerSocket(port);
			for (Map.Entry<String, Object> entry : this.map.entrySet()) {
				this.registerCenter.register(entry.getKey(), this.serviceAddress);
			}
			System.out.println("服务端已启动成功");
			// 循环监听
			while (true) {
				Socket socket = serverSocket.accept();
				this.executorService.execute(new ProcessorHandler(socket, this.map));
			}
		} catch (Exception e) {
			throw new RuntimeException("服务端创建连接失败");
		} finally {
			if (serverSocket != null) {
				try {
					serverSocket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
